@page "/datagrid/dynamicobject"


@using System.Dynamic
@using Syncfusion.Blazor.Grids

@inherits SampleBaseComponent;

<SampleDescription>
    <p>This sample demonstrates the usage of DynamicObject data binding with CRUD operations, grouping, sorting, filtering, aggregate functionalities in DataGrid component with DynamicObject.</p>
</SampleDescription>
<ActionDescription>
    <p>DynamicObject can be bound to datagrid by assigning to the <code><a target='_blank' class='code' href='https://help.syncfusion.com/cr/aspnetcore-blazor/Syncfusion.Blazor~Syncfusion.Blazor.Grids.GridModel%601~DataSource.html'>DataSource</a></code> property.</p>
    <p>The <code><a target='_blank' class='code' href='https://docs.microsoft.com/en-us/dotnet/api/system.dynamic.dynamicobject.getdynamicmembernames?view=netcore-3.1'>GetDynamicMemberNames</a></code> method of DynamicObject class must be overridden and return the property names to perform data operation and editing while using DynamicObject.</p>
</ActionDescription>
<div class="col-lg-12 control-section">
    <div class="content-wrapper">
        <div class="row">
            <SfGrid DataSource="@Orders" AllowFiltering="true" AllowSorting="true" AllowGrouping="true" AllowPaging="true" Toolbar="@ToolbarItems">
                <GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true"></GridEditSettings>
                <GridAggregates>
                    <GridAggregate>
                        <GridAggregateColumns>

                            <GridAggregateColumn Field="Freight" Type="AggregateType.Sum" Format="C2">
                                <FooterTemplate>
                                    @{
                                        var aggregate = (context as AggregateTemplateContext);
                                        <div>
                                            <p>Sum: @aggregate.Sum</p>
                                        </div>
                                    }
                                </FooterTemplate>
                            </GridAggregateColumn>
                            <GridAggregateColumn Field="Verified" Type="AggregateType.TrueCount">
                                <FooterTemplate>
                                    @{
                                        var aggregate = (context as AggregateTemplateContext);
                                        <div>
                                            <p>True Count: @aggregate.TrueCount</p>
                                        </div>
                                    }
                                </FooterTemplate>
                            </GridAggregateColumn>
                        </GridAggregateColumns>
                    </GridAggregate>
                    <GridAggregate>
                        <GridAggregateColumns>
                            <GridAggregateColumn Field="Freight" Type="AggregateType.Average" Format="C2">
                                <FooterTemplate>
                                    @{
                                        var aggregate = (context as AggregateTemplateContext);
                                        <div>
                                            <p>Average: @aggregate.Average</p>
                                        </div>
                                    }
                                </FooterTemplate>
                            </GridAggregateColumn>
                            <GridAggregateColumn Field="Verified" Type="AggregateType.FalseCount">
                                <FooterTemplate>
                                    @{
                                        var aggregate = (context as AggregateTemplateContext);
                                        <div>
                                            <p>False Count: @aggregate.FalseCount</p>
                                        </div>
                                    }
                                </FooterTemplate>
                            </GridAggregateColumn>
                        </GridAggregateColumns>
                    </GridAggregate>
                   </GridAggregates>
                <GridColumns>
                    <GridColumn Field="OrderID" HeaderText="Order ID" IsPrimaryKey="true" ValidationRules="@(new ValidationRules{ Required=true, Number=true})" TextAlign="TextAlign.Right" Width="120"></GridColumn>
                    <GridColumn Field="CustomerID" HeaderText="Customer Name" Width="120" ValidationRules="@(new ValidationRules { Required=true})"></GridColumn>
                    <GridColumn Field="Freight" HeaderText="Freight" Format="C2" TextAlign="TextAlign.Right" ValidationRules="@(new ValidationRules{ Required=true, Range = new double[]{1, 1000}})" Width="120"></GridColumn>
                    <GridColumn Field="OrderDate" HeaderText=" Order Date" ValidationRules="@(new ValidationRules{ Required=true})" Format="d" TextAlign="TextAlign.Right" Width="130" Type="ColumnType.Date"></GridColumn>
                    <GridColumn Field="ShipCountry" HeaderText="Ship Country" EditType="EditType.DropDownEdit" Width="150"></GridColumn>
                    <GridColumn Field="Verified" HeaderText="Active" DisplayAsCheckBox="true" DefaultValue="false" Width="150"></GridColumn>
                </GridColumns>
            </SfGrid>
        </div>
    </div>
</div>
@code {
    private List<string> ToolbarItems = new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" };
    public List<DynamicDictionary> Orders = new List<DynamicDictionary>() { };
    protected override void OnInitialized()
    {
        Orders = Enumerable.Range(1, 75).Select((x) =>
        {
            dynamic d = new DynamicDictionary();
            d.OrderID = 1000 + x;
            d.CustomerID = (new string[] { "ALFKI", "ANANTR", "ANTON", "BLONP", "BOLID" })[new Random().Next(5)];
            d.Freight = (new double[] { 2, 1, 4, 5, 3 })[new Random().Next(5)] * x;
            d.OrderDate = (new DateTime[] { new DateTime(2010, 11, 5), new DateTime(2018, 10, 3), new DateTime(1995, 9, 9), new DateTime(2012, 8, 2), new DateTime(2015, 4, 11) })[new Random().Next(5)];
            d.ShipCountry = (new string[] { "USA", "UK" })[new Random().Next(2)];
            d.Verified = (new bool[] { true, false })[new Random().Next(2)];
            return d;
        }).Cast<DynamicDictionary>().ToList<DynamicDictionary>();
    }
    public class DynamicDictionary : System.Dynamic.DynamicObject
    {
        Dictionary<string, object> dictionary = new Dictionary<string, object>();

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            string name = binder.Name;
            return dictionary.TryGetValue(name, out result);
        }
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            dictionary[binder.Name] = value;
            return true;
        }

        //The GetDynamicMemberNames method of DynamicObject class must be overridden and return the property names to perform data operation and editing while using DynamicObject.
        public override System.Collections.Generic.IEnumerable<string> GetDynamicMemberNames()
        {
            return this.dictionary?.Keys;
        }

    }
}
